#include <AnyToAny.h>
#include "configure.h"
#include "Curve.h"


CCurve::CCurve(void)
{
}


CCurve::~CCurve(void)
{
}
void CCurve::Create(int count)
{
	if((count%2)!=0)
		ASSERT(0);
	if(count<3)
		ASSERT(0);
	if(m_count!=count)
		ASSERT(0);
}
void CCurve::Set(int index,double y)
{
	//if(index<0||index>=m_count)
		//ASSERT(0);
	m_y[index]=y;
}
void CCurve::Go(double &a,double &b,double &c,double &d,double dy1,double dy2,double y1,double y2,double x1)
{
	a=dy1 + dy2 + 2*y1 - 2*y2;
	b=-2*dy1 - dy2 - 3*dy1*x1 - 3*dy2*x1 - 3*y1 - 6*x1*y1 + 3*y2 + 6*x1*y2;
	c=dy1*(1 + x1)*(1 + 3*x1) + x1*(dy2*(2 + 3*x1) + 6*(1 + x1)*(y1 - y2));
	d=(1 + x1)*(y1 - x1*(dy1 + dy1*x1 + dy2*x1 + y1 + 2*x1*y1)) + pow(x1,2)*(3 + 2*x1)*y2;
}
void CCurve::Go()
{
	{
		double &a=m_a[0],&b=m_b[0],&c=m_c[0],&d=m_d[0];
		double y,yp1,yp2;
		y=m_y[0];
		yp1=m_y[1];
		yp2=m_y[2];
		Go(a,b,c,d,0,-y+yp2,y,yp1,0);
	}
	int index;
	for(index=1;index<m_count-2;index++)
	{
		double &a=m_a[index],&b=m_b[index],&c=m_c[index],&d=m_d[index];
		double yn1,y,yp1,yp2;
		yn1=m_y[index-1];
		y=m_y[index];
		yp1=m_y[index+1];
		yp2=m_y[index+2];
		Go(a,b,c,d,-yn1+yp1,-y+yp2,y,yp1,index);
	}

	{
		double &a=m_a[m_count-2],&b=m_b[m_count-2],&c=m_c[m_count-2],&d=m_d[m_count-2];
		double yn1,y,yp1;
		yn1=m_y[index-3];
		y=m_y[m_count-2];
		yp1=m_y[m_count-1];
		Go(a,b,c,d,-yn1+yp1,0,y,yp1,m_count-2);
	}
}
double CCurve::Get(double x)
{
	if(x<0)
		return m_y[0];
	if(x>=m_count-1)
		return m_y[m_count-1];
	int index;
	index=(int)x;
	double a,b,c,d;
	a=m_a[index];
	b=m_b[index];
	c=m_c[index];
	d=m_d[index];
	return a*pow(x,3.0)+b*pow(x,2.0)+c*x+d;
}
